package com.serverTechnology.resource.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.serverTechnology.resource.entity.DeviceConfigEntity;
import com.serverTechnology.resource.entity.DeviceEntity;
import com.serverTechnology.resource.entity.DispositionEntity;
import com.serverTechnology.resource.entity.ManagementEntity;
import com.serverTechnology.resource.entity.dto.InsertManagementDto;
import com.serverTechnology.resource.entity.dto.ManagementInsertDto;
import com.serverTechnology.resource.entity.dto.ManagementPageDto;
import com.serverTechnology.resource.entity.dto.ManagementUpdateVo;
import com.serverTechnology.resource.entity.vo.InsertFidAndNameVo;
import com.serverTechnology.resource.entity.vo.ManagePageVo;
import com.serverTechnology.resource.entity.vo.ManagementInfoVo;
import com.serverTechnology.resource.entity.vo.MangeParamVo;
import com.serverTechnology.resource.mapper.DeviceConfigMapper;
import com.serverTechnology.resource.mapper.DeviceMapper;
import com.serverTechnology.resource.mapper.DispositionMapper;
import com.serverTechnology.resource.mapper.ManagementMapper;
import com.serverTechnology.resource.service.IManagementService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.serverTechnology.teamsGroups.entity.ProDeviceToolUser;
import com.serverTechnology.teamsGroups.mapper.ProDeviceToolMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * <p>
 * 设备、工具、工装管理 服务实现类
 * </p>
 *
 * @author 王烁
 * @since 2024-07-28
 */
@Service("ResourceServiceImpl")
public class ManagementServiceImpl extends ServiceImpl<ManagementMapper, ManagementEntity> implements IManagementService {
    @Autowired
    private ManagementMapper managementMapper;
    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private DispositionMapper dispositionMapper;
    @Autowired
    private ProDeviceToolMapper proDeviceToolMapper;
    @Autowired
    private DeviceConfigMapper deviceConfigMapper;

    public ManagementServiceImpl() {
    }

    /**
     * 新增
     *
     * @param managementInsertDto 请求参数
     */
    @Override
    public void add(ManagementInsertDto managementInsertDto) {
        ManagementEntity managementEntity = new ManagementEntity();
        BeanUtils.copyProperties(managementInsertDto, managementEntity);
        this.save(managementEntity);
    }

    /**
     * 查询设备类型
     *
     * @param deviceDistinguish 设备EQUIPMENT，工具TOOL，工装FROCK
     * @return
     */
    @Override
    public List<InsertFidAndNameVo> classifyType(String deviceDistinguish) {
        // 构建查询设备类型及其参数的 LambdaQueryWrapper
        LambdaQueryWrapper<DeviceEntity> deviceQueryWrapper = new LambdaQueryWrapper<>();
        deviceQueryWrapper.eq(DeviceEntity::getDeviceDistinguish, deviceDistinguish);
        // 进行关联查询，查询设备类型及其对应的参数
        List<DeviceEntity> deviceEntities = deviceMapper.selectList(deviceQueryWrapper);
        List<InsertFidAndNameVo> insertFidAndName = BeanUtil.copyToList(deviceEntities, InsertFidAndNameVo.class);
        return insertFidAndName;
    }

    /***
     * 根据id进行查询详情
     *
     * @param id
     * @return
     */
    @Override
    public ManagementInfoVo getManagementById(Long id) {
        // 创建返回结果对象
        ManagementInfoVo managementInfoVo = new ManagementInfoVo();

        // 构建查询条件
        LambdaQueryWrapper<ManagementEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ManagementEntity::getId, id);

        // 根据ID查询管理信息
        ManagementEntity managementEntity = managementMapper.selectOne(lambdaQueryWrapper);

        // 将查询结果复制到VO对象中
        BeanUtils.copyProperties(managementEntity, managementInfoVo);

        // 如果设备ID为空或不等于0，则查询设备信息并设置到VO中
        if (Objects.isNull(managementEntity.getId()) || !Objects.equals(managementEntity.getId(), 0)) {
            // 构建设备查询条件
            LambdaQueryWrapper<DeviceEntity> deviceQueryWrapper = new LambdaQueryWrapper<>();
            deviceQueryWrapper.eq(DeviceEntity::getId, managementEntity.getDeviceId());

            // 根据设备ID查询设备信息
            DeviceEntity deviceEntity = deviceMapper.selectOne(deviceQueryWrapper);

            // 设置设备名称到VO中
            managementInfoVo.setDeviceName(deviceEntity.getDeviceName());
        }

        return managementInfoVo;
    }

    /***
     * 根据id进行编辑
     * @param managementEntity 管理id
     * @return
     */
    @Override
    public void updateManagement(ManagementUpdateVo managementEntity) {
        ManagementEntity update = new ManagementEntity();
        BeanUtils.copyProperties(managementEntity, update);
        LambdaQueryWrapper<ManagementEntity> managementEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        managementEntityLambdaQueryWrapper.eq(ManagementEntity::getId, managementEntity.getId());
        managementMapper.update(update, managementEntityLambdaQueryWrapper);
    }


    /**
     * 根据条件获取管理页面数据
     *
     * @param resource 管理页面查询条件
     * @return 包含管理页面数据的分页结果
     */
    @Override
    public PageResult<ManagePageVo> getManagementPage(ManagementPageDto resource) {
        // 构建查询条件
        LambdaQueryWrapper<ManagementEntity> wrapper = new LambdaQueryWrapper<>();
        // 根据资源名称查询
        wrapper.eq(StringUtils.isNotEmpty(resource.getResourceName()), ManagementEntity::getResourceName, resource.getResourceName());
        // 根据创建时间查询
        if (StringUtils.isNotEmpty(resource.getCreateTime())) {
            // 使用 TO_DATE 函数将 LocalDate 转换为 Oracle 的日期格式字符串
            wrapper.apply("TRUNC(CREATE_TIME) = TO_DATE('" + resource.getCreateTime() + "', 'YYYY-MM-DD')");
        }
        //区分模块
        wrapper.eq(StringUtils.isNotEmpty(resource.getDeviceDistinguish()), ManagementEntity::getDeviceDistinguish, resource.getDeviceDistinguish());

        // 执行分页查询
        Page<ManagementEntity> sysRolePage = this.page(PageFactory.defaultPage(), wrapper);

        // 将查询结果转换为 ManagePageVo 列表
        List<ManagePageVo> managePageVos = BeanUtil.copyToList(sysRolePage.getRecords(), ManagePageVo.class);

        // 构建返回的分页结果对象
        Page<ManagePageVo> managePageVoPage = new Page<>();
        BeanUtil.copyProperties(sysRolePage, managePageVoPage);
        // 设置查询到的记录列表
        managePageVoPage.setRecords(managePageVos);

        // 使用 PageResultFactory 创建并返回分页结果
        return PageResultFactory.createPageResult(managePageVoPage);
    }

    /**
     * 根据id删除
     *
     * @param id 管理id
     * @return
     */
    @Override
    public void deleteManagement(Long id) {
        //查询是否被绑定
        LambdaQueryWrapper<ProDeviceToolUser> eq = new LambdaQueryWrapper<ProDeviceToolUser>();
        eq.eq(ProDeviceToolUser::getResourceId, id);
        Long selectCount = proDeviceToolMapper.selectCount(eq);
        //如果被绑定进行报异常
        if (selectCount > 0) {
            throw new RuntimeException("该资源已被使用，无法删除");
        }
        //如果没被绑定进行删除
        managementMapper.delete(new LambdaQueryWrapper<ManagementEntity>().eq(ManagementEntity::getId, id));
    }

    /**
     * 设备配置详情
     *
     * @param deviceId   设备ID
     * @param resourceId 资源ID
     * @return 管理参数VO列表
     */
    @Override
    public List<MangeParamVo> getManagementDetail(List<Long> deviceId, List<Long> resourceId) {
        // 查询参数名
        List<DispositionEntity> dispositionEntities = dispositionMapper.selectList(
                new LambdaQueryWrapper<DispositionEntity>()
                        .in(DispositionEntity::getDeviceId, deviceId)
        );

        // 使用Stream处理数据
        List<MangeParamVo> mangeParamVos = dispositionEntities.stream()
                .map(dispositionEntity -> {
                    // 创建管理参数VO对象
                    MangeParamVo mangeParamVo = new MangeParamVo();
                    mangeParamVo.setDispositionName(dispositionEntity.getDispositionName()); // 设置参数名
                    mangeParamVo.setDispositionId(dispositionEntity.getId()); // 设置参数ID


                    // 查询并设置设备配置信息
                    List<DeviceConfigEntity> deviceConfigEntities = deviceConfigMapper.selectList(
                            new LambdaQueryWrapper<DeviceConfigEntity>()
                                    .in(DeviceConfigEntity::getDispositionId, dispositionEntity.getId())
                                    .in(DeviceConfigEntity::getResourceId, resourceId)
                    );

                    // 如果有符合条件的设备配置信息，则设置到mangeParamVo中
                    if (!deviceConfigEntities.isEmpty()) {
                        // 假设只取第一个匹配项
                        DeviceConfigEntity deviceConfigEntity = deviceConfigEntities.get(0);
                        // 设置设备配置ID
                        mangeParamVo.setDeviceConfigId(deviceConfigEntity.getId());
                        // 设置DCOpcName
                        mangeParamVo.setDCOpcName(deviceConfigEntity.getDCOpcName());
                    }
                    // 返回设置好的管理参数VO对象
                    return mangeParamVo;
                })
                // 将Stream转换为List
                .collect(Collectors.toList());
        // 返回管理参数VO列表
        return mangeParamVos;
    }

    @Override
    public void insert(List<InsertManagementDto> insertManagementDtoList) {
        // 将DTO列表转换为实体对象列表
        List<DeviceConfigEntity> entities = insertManagementDtoList.stream()
                .map(dto -> {
                    DeviceConfigEntity entity = new DeviceConfigEntity()
                            // 设置DCOpcName
                            .setDCOpcName(dto.getDCOpcName());

                    // 判断是否存在设备配置ID，决定是插入还是更新
                    if (Objects.isNull(dto.getDeviceConfigId())) {
                        // 插入操作需要设置DispositionId和ResourceId
                        entity.setDispositionId(dto.getDispositionId())
                                .setResourceId(dto.getResourceId());
                    } else {
                        // 更新操作需要设置ID
                        entity.setId(dto.getDeviceConfigId());
                    }

                    return entity;
                })
                // 将Stream转换为List
                .collect(Collectors.toList());

        // 批量处理
        if (!entities.isEmpty()) {
            entities.forEach(entity -> {
                if (entity.getId() == null) {
                    // 插入操作
                    deviceConfigMapper.insert(entity);
                } else {
                    // 更新操作，使用ID作为条件
                    deviceConfigMapper.update(entity, new LambdaQueryWrapper<DeviceConfigEntity>()
                            .eq(DeviceConfigEntity::getId, entity.getId()));
                }
            });
        }
    }

    /***
     * 工艺接口
     * 根据设备、工装、工具进行批量查询
     *
     * @param ids
     * @return
     */
    @Override
    public List<ManagementEntity> craftByIds(List<Long> ids) {
        List<ManagementEntity> entities = managementMapper.selectList(new LambdaQueryWrapper<ManagementEntity>().in(ManagementEntity::getId, ids));
        return entities;
    }


}
